package tom.client.invoice;

import java.util.ArrayList;
import java.util.List;

import tom.client.Library;
import tom.client.LookupDialog;
import tom.shared.InvItem;
import tom.shared.Invoice;
import tom.shared.Payment;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;

import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.view.client.ListDataProvider;

import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;

import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;

public class FormPayment extends AbsolutePanel {
	private static FormPayment panel;

	public static FormPayment getPanel() {
		if (panel == null)
			panel = GWT.create(FormPayment.class);
		return panel;
	}

	private final TextBox txtInvCode;

	private static final String pWidth = "800px";

	private static final String pHeight = "500px";

	private final Button btnSave;

	private final Button btnSearchInv;

	private final CellTable<Payment> payTable;

	private Invoice inv;

	private Payment payment;

	private final ListDataProvider<InvItem> itemData = new ListDataProvider<InvItem>();
	private final CellTable<InvItem> cellTable;

	private ListDataProvider<Payment> payData = new ListDataProvider<Payment>();

	private final List<Payment> payList = new ArrayList<Payment>();

	private final List<String[]> paymethList = new ArrayList<String[]>();

	private final SingleSelectionModel<Payment> paySelection = new SingleSelectionModel<Payment>();

	private final ListBox paymethListBox;

	private double totalItem;

	private final TextBox paymentAmt;
	private final TextBox txtCreditCard;
	private final TextBox txtExpireDate;
	private final TextBox txtDocRef;
	private final Label label;

	AsyncCallback<List<String[]>> paymethCallback = new AsyncCallback<List<String[]>>() {

		@Override
		public void onFailure(Throwable caught) {

		}

		@Override
		public void onSuccess(List<String[]> result) {
			paymethList.clear();
			paymethListBox.clear();
			if (result != null) {
				for (String[] p : result) {
					paymethList.add(p);
					paymethListBox.addItem(p[0] + " - " + p[1]);
				}
			}
		}
	};
	// private final Label lbCustomerName;
	AsyncCallback<List<Payment>> payCallback = new AsyncCallback<List<Payment>>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Payment> result) {
			payList.clear();
			if (result != null) {
				for (Payment p : result) {
					payList.add(p);
				}
			}
			payData.setList(payList);
			payData.refresh();
		}
	};

	AsyncCallback<Boolean> saveCallback = new AsyncCallback<Boolean>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result)
				selectInvoice();
			else
				Window.alert("บันทึกไม่สำเร็จ");
		}
	};

	private final TextBox txtTotal;

	private final TextBox txtInvoice;

	public FormPayment() {
		setSize(pWidth, pHeight);

		label = new Label("เลขที่บิล");
		add(label, 13, 13);
		label.setSize("86px", "21px");

		txtInvoice = new TextBox();
		add(txtInvoice, 215, 10);
		txtInvoice.setSize("446px", "18px");
		txtInvoice.setEnabled(false);

		txtInvCode = new TextBox();
		txtInvCode.setMaxLength(8);
		txtInvCode.setVisible(false);
		txtInvCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					selectInvoice();

				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnSearchInv.click();
				}
			}
		});
		add(txtInvCode, 23, 32);
		txtInvCode.setSize("100px", "18px");

		btnSearchInv = new Button("?");
		btnSearchInv.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกใบส่งของจากชื่อลูกค้า", "invNo",
						txtInvCode);
			}
		});
		add(btnSearchInv, 184, 9);
		btnSearchInv.setSize("25px", "25px");

		// ClickableTextCell cell = new ClickableTextCell();

		tabPanel = new TabPanel();
		add(tabPanel, 0, 142);
		tabPanel.setSize("796px", "200px");

		txtTotal = new TextBox();
		txtTotal.setEnabled(false);
		txtTotal.setText("0.00");
		txtTotal.setAlignment(TextAlignment.RIGHT);
		txtTotal.setMaxLength(11);
		// txtTotal.setStyleName("total-box");
		add(txtTotal, 675, 92);
		txtTotal.setSize("100px", "20px");

		Label lblNewLabel = new Label("ค้างชำระ");
		add(lblNewLabel, 609, 96);
		lblNewLabel.setSize("60px", "21px");

		btnSave = new Button("ชำระเงิน");
		btnSave.setText("บันทึก");
		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				save();
			}
		});
		btnSave.setStyleName("subtitle");
		add(btnSave, 679, 10);
		btnSave.setSize("104px", "70px");

		lbTextTotal = new Label("");
		add(lbTextTotal, 216, 455);
		lbTextTotal.setSize("400px", "20px");

		panelPayment = new ScrollPanel();
		panelPayment.setSize("780px", "250px");
		tabPanel.add(panelPayment, "ชำระเงิน");

		payTable = new CellTable<Payment>();
		payTable.setStyleName("table");
		panelPayment.setWidget(payTable);
		payData.addDataDisplay(payTable);

		payTable.setPageSize(20);
		payTable.setTableLayoutFixed(true);
		payTable.setAccessKey('x');
		payTable.setSize("100%", "100%");
		payTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

		// TextColumn<Payment> colPayNo = new TextColumn<Payment>() {
		// @Override
		// public String getValue(Payment object) {
		// return object.payNo.toString();
		// }
		// };
		// colPayNo.setCellStyleNames("table");
		// payTable.addColumn(colPayNo, "Pay No.");
		// payTable.setColumnWidth(colPayNo, "30px");

		TextColumn<Payment> colPayDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.payDate.toString();
			}
		};
		colPayDate.setCellStyleNames("table");
		payTable.addColumn(colPayDate, "วันที่ชำระ");
		payTable.setColumnWidth(colPayDate, "50px");

		TextColumn<Payment> colPayAmt = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return Library.moneyFormat(object.amt);
			}
		};
		colPayAmt.setCellStyleNames("table");
		// colPayAmt.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		payTable.addColumn(colPayAmt, "จำนวนเงิน");
		payTable.setColumnWidth(colPayAmt, "50px");

		TextColumn<Payment> colMethod = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.payMethod.toString();
			}
		};
		colMethod.setCellStyleNames("table");
		payTable.addColumn(colMethod, "ชำระโดย");
		payTable.setColumnWidth(colMethod, "50px");

		// TextColumn<Payment> colLedgerAcc = new TextColumn<Payment>() {
		// @Override
		// public String getValue(Payment object) {
		// return object.ledgerAcc;
		// }
		// };
		// colLedgerAcc.setCellStyleNames("table");
		// payTable.addColumn(colLedgerAcc, "Ledger Acc");
		// payTable.setColumnWidth(colLedgerAcc, "100px");

		paymentAmt = new TextBox();
		add(paymentAmt, 151, 94);
		paymentAmt.setSize("96px", "16px");

		paymethListBox = new ListBox();
		paymethListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				paymentAmt.setVisible(paymethListBox.getSelectedIndex() > 0);
				txtCreditCard.setVisible(paymethListBox.getSelectedIndex() == 2);
				txtExpireDate.setVisible(paymethListBox.getSelectedIndex() == 2);
			}
		});
		add(paymethListBox, 151, 62);
		paymethListBox.setSize("134px", "20px");

		Label lblNewLabel_1 = new Label("ประเภทการชำระเงิน");
		add(lblNewLabel_1, 23, 64);

		Label lblNewLabel_2 = new Label("จำนวนเงิน");
		add(lblNewLabel_2, 76, 97);

		txtCreditCard = new TextBox();
		txtCreditCard.setMaxLength(20);
		add(txtCreditCard, 391, 61);
		txtCreditCard.setSize("108px", "16px");

		Label label_1 = new Label("เลขที่เช็ค");
		add(label_1, 337, 62);

		txtExpireDate = new TextBox();
		add(txtExpireDate, 599, 61);
		txtExpireDate.setSize("62px", "16px");

		Label label_2 = new Label("วันที่เช็ค");
		add(label_2, 549, 62);

		TextBox textBox = new TextBox();
		textBox.setVisible(false);
		add(textBox, 461, 92);

		Label label_3 = new Label("เลขที่บัญชี");
		add(label_3, 442, 102);
		label_3.setSize("85px", "18px");
		label_3.setVisible(false);

		tabPanel.selectTab(0);

		ScrollPanel scrollPanel = new ScrollPanel();
		tabPanel.add(scrollPanel, "รายการสินค้า");
		scrollPanel.setSize("760px", "330px");

		cellTable = new CellTable<InvItem>();
		cellTable.setStyleName("table");
		scrollPanel.setWidget(cellTable);
		cellTable.setPageSize(10);
		cellTable.setTableLayoutFixed(true);
		cellTable.setAccessKey('x');
		cellTable.setSize("100%", "100%");
		itemData.addDataDisplay(cellTable);
		// cellTable.setSelectionModel(itemSelection);

		TextColumn<InvItem> colProCode = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proCode;
			}
		};
		colProCode.setCellStyleNames("table");
		cellTable.addColumn(colProCode, "Code");
		cellTable.setColumnWidth(colProCode, "120px");

		TextColumn<InvItem> colProDescript = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proName;
			}
		};
		colProDescript.setCellStyleNames("table");
		cellTable.addColumn(colProDescript, "Name");
		cellTable.setColumnWidth(colProDescript, "250px");

		TextColumn<InvItem> colQty = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return String.valueOf(object.qty);
			}
		};
		colQty.setCellStyleNames("table");
		colQty.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);

		cellTable.addColumn(colQty, "QTY");
		cellTable.setColumnWidth(colQty, "60px");

		TextColumn<InvItem> colStock = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.stkCode;
			}
		};
		colStock.setCellStyleNames("table");
		colStock.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);

		cellTable.addColumn(colStock, "Stock");
		cellTable.setColumnWidth(colStock, "60px");

		TextColumn<InvItem> colVat = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.vatAmt);
			}
		};
		colVat.setCellStyleNames("table");
		colVat.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		cellTable.addColumn(colVat, "VAT");
		cellTable.setColumnWidth(colVat, "80px");

		TextColumn<InvItem> colAmount = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.total);
			}
		};
		colAmount.setCellStyleNames("table");
		colAmount.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		cellTable.addColumn(colAmount, "Amount");
		cellTable.setColumnWidth(colAmount, "100px");

		txtDocRef = new TextBox();
		add(txtDocRef, 95, 10);
		txtDocRef.setSize("80px", "16px");

		Button btnPay = new Button("Pay");
		btnPay.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (paymentAmt.getText() == null
						|| paymentAmt.getText().equals(""))
					paymentAmt.setText("0");
				double pay = Double.parseDouble(paymentAmt.getText());
				if (pay >= 0 && pay <= totalItem) {
					totalItem -= pay;
					payment = new Payment();
					payment.invNo = inv.invNo;
					payment.amt = pay;
					payment.systemKind = inv.systemKind;
					payment.itemKind = "P";
					 payment.payMethod = Integer.parseInt(paymethList.get(paymethListBox
					 .getSelectedIndex())[0]);
					 payment.contCode = inv.contCode;
					 payment.ledgerAcc = paymethList.get(paymethListBox
					 .getSelectedIndex())[3];
					 payList.add(payment);
					 
					// payData.refresh();
					txtTotal.setText(String.valueOf(totalItem));
					// txtTotal.setText(Library.moneyFormat(totalItem));

				} else {
					Window.alert("เกินยอดค้างชำระ");
				}
			}
		});
		add(btnPay, 293, 94);
		btnPay.setSize("70px", "24px");
		
		Button button = new Button("?");
		button.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				refresh();
			}
		});
		add(button, 369, 96);
		button.setSize("48px", "21px");

		Library.getSaleService().selectPaymeth(paymethCallback);

		clearScreen();
	}

	private void clearScreen() {
		payList.clear();
		payData.setList(payList);
		itemData.getList().clear();
		itemData.refresh();
		payData.refresh();
		// lbCustomerName.setText(null);
		txtInvoice.setText(null);
		txtInvCode.setText(null);
		txtTotal.setText(null);
		paymentAmt.setText(null);
		txtDocRef.setText(null);
		paymentAmt.setVisible(paymethListBox.getSelectedIndex() > 0);
		txtCreditCard.setVisible(paymethListBox.getSelectedIndex() == 2);
		txtExpireDate.setVisible(paymethListBox.getSelectedIndex() == 2);
	}

	private void refresh() {
		payData.refresh();
//		itemData.setList(inv.items);
//		itemData.refresh();
	}

	public void setTitle(String title) {
		clearScreen();
	}

	public void save() {
		try {

			//Library.getSaleService().insertPayment(inv.invNo, payList,
			//		saveCallback);
			// if (!txtTotalVat.getText().equals(""))
			// inv.totalVat = Double.parseDouble(txtTotalVat.getText());

			// inv.items = itemList;
		} catch (Exception e) {
			Window.alert("ERROR !" + e.getMessage());
		}
	}

	public void open(String invNo) {
		txtInvCode.setText(invNo);
		selectInvoice();
	}

	private void delete() {
		refresh();
	}

	AsyncCallback<Invoice> invCallback = new AsyncCallback<Invoice>() {

		@Override
		public void onSuccess(Invoice result) {
			if (result != null) {
				inv = result;
				if (inv.totalPaid != null) {
					totalItem = inv.totalAmt - inv.totalPaid;
					totalItem = Math.round(totalItem * 10000) / 10000.0;
				} else
					totalItem = inv.totalAmt;
				if (inv.docuKind.equals("I"))
					label.setText("เลขที่บิลเงินสด");
				if (inv.docuKind.equals("H"))
					label.setText("เลขที่บิลเงินสดอย่างย่อ");
				if (inv.docuKind.equals("C"))
					label.setText("เลขที่บิลเงินเชื่อ");
				txtDocRef.setText(inv.docRef);
				txtInvoice.setText(inv.contactAddr);
				// txtTotal.setText(Library.moneyFormat(totalItem));
				txtTotal.setText(String.valueOf(totalItem));
				paymentAmt.setText(txtTotal.getText());
				itemData.setList(inv.items);
				btnSave.setEnabled(inv.status.equals("0"));
				Library.getSaleService().selectPayment(
						Integer.parseInt(txtInvCode.getText()), payCallback);
			} else
				Window.alert("ไม่พบใบส่งของหมายเลขนี้");
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert(Library.ERROR_MESSAGE);
		}
	};

	private final Label lbTextTotal;
	private final TabPanel tabPanel;
	private final ScrollPanel panelPayment;

	private void selectInvoice() {
		Library.getSaleService().selectInvoice(
				Integer.parseInt(txtInvCode.getText()), invCallback);
	}
}
